package com.gitee.wsl.data.recycler

/**
 * API for object pools that control creation and possible reuse of
 * objects that are costly to create (often things like encoding/decoding buffers).
 *
 *
 * Also contains partial (base) implementations for pools that use different
 * strategies on retaining objects for reuse.
 * Following implementations are included:
 *
 *  * [NonRecyclingPoolBase] which does not retain or recycle anything and
 * will always simply construct and return new instance when
 * `acquireBufferRecycler` is called
 *
 *  * [ThreadLocalPoolBase] which uses [ThreadLocal] to retain at most
 * 1 object per [Thread].
 *
 *  * [BoundedPoolBase] is "bounded pool" and retains at most N objects (default value being
 * [BoundedPoolBase.DEFAULT_CAPACITY]) at any given time.
 *
 *  * Two implementations -- [ConcurrentDequePoolBase], [LockFreePoolBase]
 * -- are "unbounded" and retain any number of objects released: in practice
 * it is at most the highest number of concurrently used [BufferRecycler]s.
 *
 *
 *
 *
 *
 * Default implementations are also included as nested classes.
 *
 * @param <P> Type of Objects pool recycles
 *
 * @since 2.16
</P> */
interface RecyclerPool<P : RecyclerPool.WithPool<P>>  {
    /**
     * Simple add-on interface that poolable entities must implement.
     *
     * @param <P> Self type
    </P> */
    interface WithPool<P : WithPool<P>> {
        /**
         * Method to call to add link from pooled item back to pool
         * that handles it
         *
         * @param pool Pool that "owns" pooled item
         *
         * @return This item (for call chaining)
         */
        fun withPool(pool: RecyclerPool<P>): P

        /**
         * Method called when this item is to be released back to the
         * pool that owns it (if any)
         */
        fun releaseToPool()
    }

    /**
     * Method called to acquire a Pooled value from this pool
     * AND make sure it is linked back to this
     * [RecyclerPool] as necessary for it to be
     * released (see [.releasePooled]) later after usage ends.
     * Actual acquisition is done by a call to [.acquirePooled].
     *
     *
     * Default implementation calls [.acquirePooled] followed by
     * a call to [WithPool.withPool].
     *
     * @return Pooled instance for caller to use; caller expected
     * to call [.releasePooled] after it is done using instance.
     */
    fun acquireAndLinkPooled(): P {
        return acquirePooled().withPool(this)
    }

    /**
     * Method for sub-classes to implement for actual acquire logic; called
     * by [.acquireAndLinkPooled].
     *
     * @return Instance acquired (pooled or just constructed)
     */
    fun acquirePooled(): P

    /**
     * Method that should be called when previously acquired (see [.acquireAndLinkPooled])
     * pooled value that is no longer needed; this lets pool to take ownership
     * for possible reuse.
     *
     * @param pooled Pooled instance to release back to pool
     */
    fun releasePooled(pooled: P)

    /**
     * Optional method that may allow dropping of all pooled Objects; mostly
     * useful for unbounded pool implementations that may retain significant
     * memory and that may then be cleared regularly.
     *
     * @since 2.17
     *
     * @return `true` If pool supports operation and dropped all pooled
     * Objects; `false` otherwise.
     */
    fun clear(): Boolean {
        return false
    }

    /**
     * Diagnostic method for obtaining an estimate of number of pooled items
     * this pool contains, available for recycling.
     * Note that in addition to this information possibly not being available
     * (denoted by return value of `-1`) even when available this may be
     * just an approximation.
     *
     *
     * Default method implementation simply returns `-1` and is meant to be
     * overridden by concrete sub-classes.
     *
     * @return Number of pooled entries available from this pool, if available;
     * `-1` if not.
     *
     * @since 2.18
     */
    fun pooledCount(): Int {
        return -1
    }

    companion object
}
